package com.mhjy.synchro.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mhjy.synchro.repository.entity.*;
import com.mhjy.synchro.repository.model.*;
import com.mhjy.synchro.service.*;
import com.fasterxml.jackson.core.type.TypeReference;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;


@Service
public class SynchroService implements ISynchroService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RestTemplate restTemplate;

    private static final String GetMemberUrl = "http://localhost:9215/api/base/getSimpleMember";

    private static final String InputMemberUrl = "http://localhost:9215/api/base/inputMember";

    private static final String InputSoUrl = "http://localhost:9215/api/base/inputSo";


    @Autowired
    private IOldieBaseInfoService oldieBaseInfoService;


    @Autowired
    private ISettlementRecordSummaryService settlementRecordSummaryService;

    @Autowired
    private IRefundApplicationSummaryService refundApplicationSummaryService;

    @Autowired
    private IAdvanceMonthbillSummaryService advanceMonthbillSummaryService;


    @Autowired
    private IAdvanceMonthbillDetailService advanceMonthbillDetailService;

    @Autowired
    private IRefundApplicationDetailService refundApplicationDetailService;

    @Autowired
    private ISettlementRecordDetailService settlementRecordDetailService;


    @Override
    public BaseResultModel SynchroMember() throws JsonProcessingException {

        String resultStr = GetData(GetMemberUrl);
        logger.info(resultStr);
        BaseResultModel getMember = oldieBaseInfoService.GetAll();
        if (!getMember.getCode().equals(0))
            return new BaseResultModel(99, "本地库获取老人信息失败" + getMember.getMessage());

        List<MbMemberInputModel> inputModels = new ArrayList<>();
        List<OldieBaseInfoEntity> entities = (List<OldieBaseInfoEntity>) getMember.getData();
        ObjectMapper mapper = new ObjectMapper();
        BaseResultModel resultModel = mapper.readValue(resultStr, new TypeReference<BaseResultModel<List<SimpleNhMbMemberModel>>>() {
        });

        if (resultModel.getCode().equals(0) || resultModel.getCode().equals(98)) {
            List<SimpleNhMbMemberModel> memberList = (List<SimpleNhMbMemberModel>) resultModel.getData();

            if (memberList == null)
                memberList = new ArrayList<>();

            for (OldieBaseInfoEntity entity : entities) {
                Optional<SimpleNhMbMemberModel> k = memberList.stream().filter(x -> x.getMbNo().equals(entity.getOldieNo()) && x.getOrgId().equals(entity.getOrgNo())).findFirst();
                if (!k.isPresent()) {
                    MbMemberInputModel newMember = new MbMemberInputModel();
                    newMember.setAddress(entity.getFamilyAddress());
                    if (entity.getBirthday() != null) {
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                        newMember.setBirthday(df.format(entity.getBirthday()));
                    }

                    newMember.setCareLevel(GetCareLevel(entity.getNlvName()));
                    newMember.setStatus(GetStatus(entity.getDealStatus()));
                    newMember.setIdCardNo(entity.getIdNo());
                    newMember.setMbName(entity.getOldieName());
                    newMember.setMbNo(entity.getOldieNo());
                    newMember.setOrgId(entity.getOrgNo());
                    newMember.setMobile(entity.getPhoneNum());
                    newMember.setStatus(GetStatus(entity.getDealStatus()));
                    newMember.setSex(entity.getSex().equals(0) ? "01" : "02");
                    inputModels.add(newMember);
                }
            }
            if (inputModels.size() > 0) {
                String inputStr = PostData(InputMemberUrl, mapper.writeValueAsString(inputModels));
                logger.info(inputStr);
            }

            return new BaseResultModel(0, "inputStr", inputModels);

        } else
            return new BaseResultModel(99, "获取NH老人信息失败");
    }


    @Override
    public BaseResultModel SynchroSoDetail() throws JsonProcessingException {
        BaseResultModel settlementDeteailResult = settlementRecordDetailService.GetSynchroRecord();
        BaseResultModel refundDeteailResult = refundApplicationDetailService.GetSynchroRecord();
        BaseResultModel advanceMonthbillDeteailResult = advanceMonthbillDetailService.GetSynchroRecord();
        if (!settlementDeteailResult.getCode().equals(0) && !refundDeteailResult.getCode().equals(0) && !advanceMonthbillDeteailResult.getCode().equals(0))
            return new BaseResultModel(99, "没有需要同步的数据");

        ObjectMapper mapper = new ObjectMapper();


        if (settlementDeteailResult.getCode().equals(0)) {
            Integer count = 1000;
            for (SettlementRecordDetailEntity entity : (List<SettlementRecordDetailEntity>) settlementDeteailResult.getData()) {

                if (entity.getFeeAmount() == null || entity.getFeeAmount() <= 0)
                    continue;


                SettlementRecordSummaryEntity mine = settlementRecordSummaryService.getById(entity.getSrsId());
                SimpleDateFormat formatter1 = new SimpleDateFormat("yyyyMM");
                SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");


                SoDetailInputModel soDetailInputModel = new SoDetailInputModel();
                soDetailInputModel.setSoNo(mine.getPrintNo() + count);
                soDetailInputModel.setOrgId(entity.getOrgNo());
                soDetailInputModel.setProductCode(entity.getFeeNo());
                soDetailInputModel.setProductDesc(entity.getFeeName());
                soDetailInputModel.setLineNo("1");
                soDetailInputModel.setProductType("P");
                soDetailInputModel.setProductPrice(entity.getFeeAmount());
                soDetailInputModel.setSoPrice(entity.getFeeAmount());
                soDetailInputModel.setDiscountOffAmt(0.0d);
                soDetailInputModel.setSoQty(1.0d);
                soDetailInputModel.setProductPeriod(formatter1.format(entity.getOperateDate()));


                SoMasterInputModel soMasterInputModel = new SoMasterInputModel();
                soMasterInputModel.setMbNo(mine.getOldieNo());
                soMasterInputModel.setMbName(mine.getOldieName());
                soMasterInputModel.setOrgId(entity.getOrgNo());
                soMasterInputModel.setSoNo(mine.getPrintNo() + count);

                String soType;
                String tips = entity.getFeeNo().substring(0,1);
                if (StrIsAlpha(tips)) {
                    soType = entity.getFeeNo().substring(1, 4);
                } else
                    soType = entity.getFeeNo();
                soMasterInputModel.setSoType(soType);
                soMasterInputModel.setSoRetailAmt(entity.getFeeAmount());
                soMasterInputModel.setSoAmt(entity.getFeeAmount());
                soMasterInputModel.setDiscountOffAmt(0d);
                if (mine.getPaymentType().equals("1"))
                    soMasterInputModel.setPayBy("02");

                if (mine.getPaymentType().equals("2"))
                    soMasterInputModel.setPayBy("01");

                soMasterInputModel.setSoDate(formatter2.format(entity.getOperateDate()));
                soMasterInputModel.setSoPeriod(formatter1.format(entity.getOperateDate()));

                InsertSoModel model = new InsertSoModel();
                model.setSoDetail(soDetailInputModel);
                model.setSoMaster(soMasterInputModel);

                String resultStr = PostData(InputSoUrl, mapper.writeValueAsString(model));
                BaseResultModel resultModel = mapper.readValue(resultStr, BaseResultModel.class);
                if (resultModel.getCode().equals(0)) {
                    entity.setSyncTag(1);
                    Boolean k = settlementRecordDetailService.updateById(entity);
                }
                count += 1;
            }

        }

        if (refundDeteailResult.getCode().equals(0)) {
            Integer count = 1000;
            for (RefundApplicationDetailEntity entity : (List<RefundApplicationDetailEntity>) refundDeteailResult.getData()) {
                RefundApplicationSummaryEntity mine = refundApplicationSummaryService.getById(entity.getRasId());
                SimpleDateFormat formatter1 = new SimpleDateFormat("yyyyMM");
                SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");

                SoDetailInputModel soDetailInputModel = new SoDetailInputModel();
                soDetailInputModel.setOrgId(entity.getOrgNo());
                soDetailInputModel.setProductCode(entity.getFeeNo());
                soDetailInputModel.setProductDesc(entity.getFeeName());
                soDetailInputModel.setLineNo("1");
                soDetailInputModel.setProductType("P");
                soDetailInputModel.setDiscountOffAmt(0.0d);
                soDetailInputModel.setSoQty(1.0d);
                soDetailInputModel.setSoPrice(0 - entity.getFeeAmount());
                soDetailInputModel.setProductPrice(0 - entity.getFeeAmount());
                soDetailInputModel.setProductPeriod(formatter1.format(entity.getOperateDate()));
                soDetailInputModel.setSoNo(mine.getRefundNo() + count);


                SoMasterInputModel soMasterInputModel = new SoMasterInputModel();
                soMasterInputModel.setMbNo(mine.getOldieNo());
                soMasterInputModel.setMbName(mine.getOldieName());
                soMasterInputModel.setOrgId(entity.getOrgNo());
                soMasterInputModel.setSoNo(mine.getRefundNo() + count);//待决定

                if (StringUtils.isBlank(entity.getFeeNo())) {
                    logger.info("退款记录Id:" + entity.getId() + "类型为空：" + entity.getFeeNo());
                    continue;
                }
                String soType;
                String tips = entity.getFeeNo().substring(1);
                if (StrIsAlpha(tips)) {
                    soType = entity.getFeeNo().substring(1, 3);
                } else
                    soType = entity.getFeeNo();

                soMasterInputModel.setSoType(soType);//暂定
                soMasterInputModel.setSoRetailAmt(0 - entity.getFeeAmount());
                soMasterInputModel.setSoAmt(0 - entity.getFeeAmount());
                soMasterInputModel.setDiscountOffAmt(0d);

                if (mine.getRefundType().equals("XJ"))
                    soMasterInputModel.setPayBy("02");

                if (mine.getRefundType().equals("YHK"))
                    soMasterInputModel.setPayBy("01");

                if (mine.getRefundType().equals("YCK"))
                    soMasterInputModel.setPayBy("03");

                soMasterInputModel.setSoDate(formatter2.format(entity.getOperateDate()));
                soMasterInputModel.setSoPeriod(formatter1.format(entity.getOperateDate()));

                InsertSoModel model = new InsertSoModel();
                model.setSoDetail(soDetailInputModel);
                model.setSoMaster(soMasterInputModel);

                String resultStr = PostData(InputSoUrl, mapper.writeValueAsString(model));
                BaseResultModel resultModel = mapper.readValue(resultStr, BaseResultModel.class);
                if (resultModel.getCode().equals(0)) {
                    entity.setSyncTag(1);
                    Boolean k = refundApplicationDetailService.updateById(entity);
                }
                count += 1;
            }
        }

        if (advanceMonthbillDeteailResult.getCode().equals(0)) {
            Integer count = 1000;
            for (AdvanceMonthbillDetailEntity entity : (List<AdvanceMonthbillDetailEntity>) advanceMonthbillDeteailResult.getData()) {
                AdvanceMonthbillSummaryEntity mine = advanceMonthbillSummaryService.getById(entity.getMbsId());
                SoDetailInputModel soDetailInputModel = new SoDetailInputModel();
                soDetailInputModel.setOrgId(entity.getOrgNo());
                soDetailInputModel.setProductCode(entity.getFeeNo());
                soDetailInputModel.setProductDesc(entity.getFeeName());
                soDetailInputModel.setLineNo("1");
                soDetailInputModel.setProductType("P");
                soDetailInputModel.setDiscountOffAmt(entity.getFeeAmount() - entity.getDiscountAmount());
                soDetailInputModel.setSoQty(entity.getQuantity());
                soDetailInputModel.setSoPrice(entity.getDiscountAmount());
                SimpleDateFormat formatter1 = new SimpleDateFormat("yyyyMM");
                SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");
                soDetailInputModel.setProductStartDate(formatter2.format(entity.getFeeTimeStart()));
                soDetailInputModel.setProductEndDate(formatter2.format(entity.getFeeTimeEnd()));
                soDetailInputModel.setProductPeriod(formatter1.format(entity.getOperateDate()));
                soDetailInputModel.setProductPrice(entity.getPrice());
                soDetailInputModel.setSoNo(mine.getSeqNo() + count);


                SoMasterInputModel soMasterInputModel = new SoMasterInputModel();
                soMasterInputModel.setMbNo(mine.getOldieNo());
                soMasterInputModel.setMbName(mine.getOldieName());
                soMasterInputModel.setOrgId(entity.getOrgNo());
                soMasterInputModel.setSoNo(mine.getSeqNo() + count);//待决定


                if (StringUtils.isBlank(entity.getFeeNo())) {
                    logger.info("退款记录Id:" + entity.getId() + "类型为空：" + entity.getFeeNo());
                    continue;
                }
                String soType;
                String tips = entity.getFeeNo().substring(1);
                if (StrIsAlpha(tips)) {
                    soType = entity.getFeeNo().substring(1, 3);
                } else
                    soType = entity.getFeeNo();

                soMasterInputModel.setSoType(soType);//暂定

                soMasterInputModel.setSoRetailAmt(entity.getFeeAmount());
                soMasterInputModel.setSoAmt(entity.getDiscountAmount());
                soMasterInputModel.setDiscountOffAmt(entity.getFeeAmount() - entity.getDiscountAmount());
                if (mine.getPaymentType().equals("1"))
                    soMasterInputModel.setPayBy("02");

                if (mine.getPaymentType().equals("2"))
                    soMasterInputModel.setPayBy("01");

                soMasterInputModel.setSoDate(formatter2.format(entity.getOperateDate()));
                soMasterInputModel.setSoPeriod(formatter1.format(entity.getOperateDate()));

                InsertSoModel model = new InsertSoModel();
                model.setSoDetail(soDetailInputModel);
                model.setSoMaster(soMasterInputModel);

                String resultStr = PostData(InputSoUrl, mapper.writeValueAsString(model));
                BaseResultModel resultModel = mapper.readValue(resultStr, BaseResultModel.class);
                if (resultModel.getCode().equals(0)) {
                    entity.setSyncTag(1);
                    Boolean k = advanceMonthbillDetailService.updateById(entity);
                }
                count += 1;
            }
        }

        return new BaseResultModel(0, "同步完成");
    }


    public boolean StrIsAlpha(String str) {
        if (str == null) return false;
        return str.matches("[a-zA-Z]+");
    }

    private String PostData(String url, String dataStr) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> request = new HttpEntity<>(dataStr, headers);
        ResponseEntity<String> postForEntity = restTemplate.postForEntity(url, request, String.class);
        String body = postForEntity.getBody();
        return body;
    }

    private String GetData(String url) {
        ResponseEntity<String> postForEntity = restTemplate.getForEntity(url, String.class);
        String body = postForEntity.getBody();
        return body;
    }

    private String GetCareLevel(String name) {
        if (name == null)
            return "";

        switch (name) {
            case "一级护理A":
                return "10";
            case "一级护理B":
                return "20";
            case "二级护理":
                return "30";
            case "三级护理":
                return "40";
            case "专护":
                return "50";
            case "特殊护理":
                return "60";
            case "一级护理C":
                return "70";
            default:
                return "";
        }
    }

    private String GetStatus(Integer id) {
        if (id == null)
            return "01";

        switch (id) {
            case 0:
                return "01";
            case 1:
                return "01";
            case 2:
                return "02";
            case 3:
                return "03";
            default:
                return "03";
        }
    }
}
